/******************************************************************************
 *      Mestrado em Ciência da Computação - UFMS
 *		Redes de Computadores - Prof. Dr. Ronaldo Alves Ferreira
 *		Alunos: Geraldo Landre, Marcel Tolentino, Vinícius Bueno
 *****************************************************************************/

#ifndef PORT_H
#define	PORT_H

#include "defines.h"
#include "queue_int.h"


//
// Definir erros aqui
//
typedef enum {
    PERR_BUFFBOUND   = -5,
    PERR_NOTOCCUPIED = -11,
    PERR_OCCUPIED = -12
} port_error;

//
// Estados possiveis para as ports
//
typedef enum {
    PORT_FREE         = 1,
    PORT_OCCUPIED     = 2
} port_state;

// ----------------------------- PORT ----------------------------------

// estrutura a ser usada para manipular ports
typedef struct {
    sync_queue_int *msg_buffer;
    u_short buff_max_length;

    port_state state;
} port;

/**
 * Cria uma nova port, com buffer para mensagens atribuido.
 * Insere nova port no array de ports
 * @param bufflength
 * @return id da port
 */
int newport_network(u_short p, u_short bufflength);
int newport_kernel(u_short p, u_short bufflength);
int newport(u_short p, u_short bufflength);

void freeport(u_short i);

/**
 * Altera o tamanho da porta
 * @param id id da port
 */
void resizeport(u_short i, u_short newlength);

int port_sendmsg(u_short id_dest, int msg);
// caso precise ser usado no processo principal
void _port_sendmsg(u_short id_dest, int msg);

int port_recvmsg(u_short i);

u_short port_countmsg(u_short i);
u_short port_maxlength(u_short i);

// ---------------------- BUFFER de PORTS ------------------------------------

#define TCP_NPORTS 65535
#define TCP_NPORTS_KERNEL 1024

port **port_buff;
sync_queue_int *free_ports_kernel;
sync_queue_int *free_ports_network;
sem_t port_buff_mutex;

// inicializa o buffer de ports
void init_port_buff();
// libera o buffer de ports
void destroy_port_buff();

//
// testing
//
const char* str_port_state(port_state state);
const char* str_port_error(int error);
void print_port(int i);
void print_port_buff();

#endif	/* PORT_H */

